/*
 * Copyright 2013 Agustina Martinez-Garcia

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
package uk.ljmu.qudexapps.manager.actions;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.igfay.jfig.JFig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.binding.message.MessageBuilder;
import org.springframework.binding.message.MessageContext;
import org.springframework.webflow.execution.RequestContext;

import uk.ljmu.qudexapps.manager.domain.FilesModel;
import uk.ljmu.qudexapps.manager.services.SpreadsheetService;
import uk.ljmu.qudexapps.manager.utilities.TempDirectory;
import uk.ljmu.qudexapps.xmllib.exceptions.FoxmlException;

public class CollectionActions {

    private String fileSeparator = System.getProperty("file.separator");

    @Autowired
    private SpreadsheetService spService;
    private TempDirectory dir;

    /**
     * @param spService
     *            the spService to set
     */
    public void setSpService(SpreadsheetService spService) {
	this.spService = spService;
    }

    /**
     * @return the spService
     */
    public SpreadsheetService getSpService() {
	return spService;
    }

    /**
     * @param dir
     *            the dir to set
     */
    public void setDir(TempDirectory dir) {
	this.dir = dir;
    }

    /**
     * @return the dir
     */
    public TempDirectory getDir() {
	return dir;
    }

    /**
     * POJO which processes a collection-level spreadsheet and creates the
     * collection(s) in the Fedora repository
     * 
     * @param context
     *            flowContextRequest object
     * @return "success" or "error" strings
     * 
     * @throws Exception
     *             WebFlow exceptions not captured
     */
    public String processCollectionSpreadsheet(RequestContext context)
	    throws Exception {

	FilesModel files = (FilesModel) context.getFlowScope()
		.get("filesModel");

	// Holds Error messages in a clean way so actions themselves will handle
	// business logic exceptions and then
	// the action will redirect with proper error codes + messages -->
	// error() or success()
	MessageContext messages = context.getMessageContext();
	this.spService.setFileType(files.getSpreadsheet().getContentType());
	this.spService.getFiles().setSpreadsheet(files.getSpreadsheet());
	this.spService.getFiles().setOption(files.getOption());
	this.spService.setQudexCollections(true);
	try {
	    String fullPath = (files.getTempDirPath()
		    .endsWith(this.fileSeparator)) ? files.getTempDirPath()
		    + files.getSpreadsheet().getOriginalFilename() : files
		    .getTempDirPath()
		    + this.fileSeparator
		    + files.getSpreadsheet().getOriginalFilename();
	    File file = new File(fullPath);
	    this.writeToFile(files.getSpreadsheet().getInputStream(), file);
	    String completeUrl = JFig.getInstance().getValue("fedoraServer",
		"fileServletUrl");
	    fullPath = completeUrl + "?fileName=" + 
	    files.getSpreadsheet().getOriginalFilename() + "&type=";
	    this.spService.setOriginalSpreadsheetPath(fullPath);
	    
	    spService.ingestCollectionsSpreadsheet();
	    //After ingest clean
	    spService.setOriginalSpreadsheetPath("");
	    if (!(file.delete())) {
		 messages.addMessage(new MessageBuilder().error().code(
		    "foxmlError.collection.IO").build());
		 return "error";
	    }
	    spService.getFiles().setCollectionsIds("");
	    context.getFlowScope().put("results", this.spService.getResults());
	    return "success";
	} catch (FoxmlException ex) {
	    // Manage service logic exceptions
	    messages.addMessage(new MessageBuilder().error().code(
		    "foxmlError.collection.General").build());
	    return "error";
	} catch (IOException e) {
	    messages.addMessage(new MessageBuilder().error().code(
		    "foxmlError.collection.IO").build());
	    return "error";
	} catch (Exception e) {
	    messages.addMessage(new MessageBuilder().error().code(
		    "foxmlError.collection.Other").build());
	    return "error";
	}
    }

    /**
     * 
     * @param context
     * @return
     * @throws Exception
     *             webFlow exceptions not captured
     */
    public String checkSelectedCollections(RequestContext context)
	    throws Exception {

	String collectionsIds = (String) context.getRequestParameters().get(
		"collectionsIds");
	if (collectionsIds == null) {
	    context.getMessageContext().addMessage(
		    new MessageBuilder().error().code("emptyCollectionIds")
			    .build());
	    return "error";
	}

	String[] arrayIds;

	arrayIds = collectionsIds.split(";");

	if (arrayIds.length == 0 || arrayIds[0] == "") {
	    context.getMessageContext().addMessage(
		    new MessageBuilder().error().code("emptyCollectionIds")
			    .build());
	    return "error";
	}
	// TODO Double Check this is working
	this.spService.getFiles().setCollectionsIds(
		context.getRequestParameters().get("collectionsIds"));
	context.getFlowScope().put("cols",
		context.getRequestParameters().get("collectionsIds"));
	context.getExternalContext().recordResponseComplete();
	return "success";
    }

    private void writeToFile(InputStream is, File file) {
	try {
	    DataOutputStream out = new DataOutputStream(
		    new BufferedOutputStream(new FileOutputStream(file)));
	    int c;
	    while ((c = is.read()) != -1) {
		out.writeByte(c);
	    }
	    is.close();
	    out.close();
	} catch (IOException e) {
	    System.err.println("Error Writing/Reading Streams.");
	}
    }
}
